home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Leser 15 / Amiga Plus Leser CD 15.iso / Tools / Development / yacas_alg / yacas_morphos / share / yacas / addons / gnuplot.ys < prev    next >
Encoding:
Text File  |  2002-03-13  |  3.6 KB  |  165 lines

  1.  
  2. /*
  3. Plotting a one-dimensional function: an example using threading
  4.  
  5. Most programming languages in use are imperial, and thus force the
  6. programmer to write out an algorithm in detail, step by step
  7. instructions. The interpreter language in Yacas is one derived
  8. from Lisp, and thus has many functional properties. Functional
  9. descriptions of algorithms are usually a lot shorter.
  10.  
  11. This example shows the use of threading, to write a function plotter
  12. in a few lines. It also shows how to build up a nice program from
  13. small functions.
  14.  
  15. Threading can be used to evaluate a function at multiple values:
  16.     x:={a,b,c};
  17.     Sin(x);
  18.  
  19. should return something to the effect of
  20.  
  21.     {Sin(a),Sin(b),Sin(c)}
  22.  
  23.  
  24. This can be useful for plotting functions. For instance,
  25.  
  26.     (0 .. 5)/5
  27.  
  28.  
  29. evaluates to
  30.  
  31.     {0,1/5,2/5,3/5,4/5,1};
  32.  
  33. And
  34.  
  35.     N((0 .. 5)/5)
  36.  
  37. evaluates to
  38.  
  39.     {0,0.2,0.4,0.6,0.8,1};
  40.  
  41. So this in effect generates a list of values from 0 to 1 in 5 steps.
  42. So entering
  43.  
  44.     a + (0 .. 5)/5
  45.  
  46. will result in
  47.  
  48.     {a,a+1/5,a+2/5,a+3/5,a+4/5,a+1};
  49.  
  50. which is a list from a to (a+1).
  51.  
  52. A list of values we want to evaluate the
  53. function at can then be built like this:
  54.  
  55. */
  56.     Iterate(start_IsNumber, end_IsNumber, steps_IsInteger) <--
  57.         start + ( (0 .. steps)/steps) * (end-start);
  58.  
  59. /*
  60. This function uses the
  61. threading facilities, where addition, multiplication and division
  62. on lists work on a per-element basis.
  63.  
  64. Save the function 'Iterate' in a file, start up yacas, and load the file
  65. using Load("file"), and then type
  66.  
  67.     Iterate(0,1,4);
  68.  
  69. This should return {0,1/4,1/2,3/4,1}
  70.  
  71. Now, type
  72.  
  73.     x:=Iterate(0,1,4);
  74.     N(Sin(x));
  75.  
  76. This should give you a list of Sin(x) evaluated at the four points.
  77. Again N(...) should be used, to force evaluation of Sin on a number.
  78. Now, if you type
  79.  
  80.     Transpose({x,N(Sin(x))});
  81.  
  82. You will get a list of the form
  83.  
  84.     {
  85.       {x0, Sin(x0)},
  86.       {x1, Sin(x1)},
  87.       {x2, Sin(x2)},
  88.       {x3, Sin(x3)}
  89.     }
  90.  
  91. We need to be able to write this out as something a plotting library
  92. like gnuplot accepts. Suppose we create a function
  93. */
  94.  
  95.     WriteTuple(tuple_IsList) <--
  96.       [
  97.         ForEach(item,tuple)
  98.         [
  99.           Write(item);
  100.           Space();
  101.         ];
  102.         NewLine();
  103.       ];
  104.  
  105. /*
  106. We could then write out each item in the list:
  107.  
  108.     list:=Transpose(x,N(Sin(x)));
  109.     ForEach(item,list) WriteTuple(item);
  110.  
  111.  
  112. To store this to a file, ToFile can be used:
  113.  
  114.     ToFile("data.dat") ForEach(item,list) WriteTuple(item);
  115.  
  116. Plotting in gnuplot can then be achieved by using "plot 'data.dat' with lines" in
  117. gnuplot.
  118.  
  119. So the full sequence for plotting Sin(x) with x from -3 to 3 in 10 steps
  120. would become:
  121.  
  122.     Load("myplot.ys");
  123.     x:=Iterate(-3,3,10);
  124.     list:=Transpose({x,N(Sin(x))});
  125.     ToFile("data.dat") ForEach(item,list) WriteTuple(item);
  126.  
  127. Where the file "myplot" should contain the functions Iterate and WriteTuple.
  128.  
  129. */
  130.  
  131. PlotX(from_IsNumber,to_IsNumber,steps_IsInteger,_function) <--
  132. [
  133.   Local(x,list);
  134.   x:=N(Iterate(from,to,steps));
  135.   function:=N(function);
  136.   If(IsList(function[1]),function:=function[1]);
  137.   list:=Transpose({x,function});
  138.   ForEach(item,list) WriteTuple(item);
  139. ];
  140. /* HoldArg("PlotX",arg4); */
  141.  
  142. 10 # GnuPlot(from_IsNumber,to_IsNumber,steps_IsInteger,list_IsList) <--
  143. [
  144.   Local(i,exec);
  145.   exec := "plot ";
  146.   For(i:=1,i<=Length(list),i++)
  147.   [
  148.     ToFile("gnudata.in":String(i))PlotX(from,to,steps,list[i]);
  149.     exec:=exec:"\"gnudata.in":String(i):"\" with lines";
  150.     If(i<Length(list),exec:=exec:", ");
  151.   ];
  152.   ToFile("gnuplot.in")WriteString(exec);
  153.   SystemCall("gnuplot -persist gnuplot.in");
  154. ];
  155.  
  156. 20 # GnuPlot(from_IsNumber,to_IsNumber,steps_IsInteger,_function) <--
  157. [
  158.   ToFile("gnudata.in")PlotX(from,to,steps,function);
  159.   ToFile("gnuplot.in")WriteString("plot \"gnudata.in\" with lines");
  160.   SystemCall("gnuplot -persist gnuplot.in");
  161. ];
  162. HoldArg("GnuPlot",arg4);
  163.  
  164.  
  165.